package cn.ht.jywrwater.module.ht.controller.admin.dashboard.dashboard;

import cn.ht.jywrwater.framework.common.pojo.CommonResult;
import cn.ht.jywrwater.module.ht.controller.admin.dashboard.dashboard.vo.WaterQualityAlertDashboard;
import cn.ht.jywrwater.module.ht.controller.admin.dashboard.dashboard.vo.WaterUseRatio;
import cn.ht.jywrwater.module.ht.controller.admin.dashboard.dashboard.vo.WaterUseStaticsDashboard;
import cn.ht.jywrwater.module.ht.controller.admin.statisticsdevicecount.vo.StatisticsDeviceCountRespVO;
import cn.ht.jywrwater.module.ht.convert.statisticsdevicecount.StatisticsDeviceCountConvert;
import cn.ht.jywrwater.module.ht.dal.dataobject.statisticsdevicecount.StatisticsDeviceCountDO;
import cn.ht.jywrwater.module.ht.dal.dataobject.watercount.WaterCountDO;
import cn.ht.jywrwater.module.ht.dal.dataobject.waterqualityalertcount.WaterQualityAlertCountDO;
import cn.ht.jywrwater.module.ht.dal.mysql.statisticsdevicecount.StatisticsDeviceCountMapper;
import cn.ht.jywrwater.module.ht.dal.mysql.watercount.WaterCountMapper;
import cn.ht.jywrwater.module.ht.dal.mysql.waterqualityalertcount.WaterQualityAlertCountMapper;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cglib.core.Local;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

import static cn.ht.jywrwater.framework.common.pojo.CommonResult.success;

@Tag(name = "大屏 - 首页大屏数据")
@RestController
@RequestMapping("/ht/dashboard")
@Validated
public class DashboardController {

    @Resource
    private StatisticsDeviceCountMapper statisticsDeviceCountMapper;

    @Resource
    private WaterQualityAlertCountMapper waterQualityAlertCountMapper;


    @Resource
    private WaterCountMapper waterCountMapper;

    @GetMapping("/statistics-device-count-list")
    @Operation(summary = "获得设备在线统计列表")
    public CommonResult<List<StatisticsDeviceCountRespVO>> getStatisticsDeviceCountList() {
        List<StatisticsDeviceCountDO> list = statisticsDeviceCountMapper.selectList();
        return success(StatisticsDeviceCountConvert.INSTANCE.convertList(list));
    }

    @GetMapping("/water-quality-alert-list")
    @Operation(summary = "获得水质统计列表")
    public CommonResult<WaterQualityAlertDashboard> getWaterQualityAlertCountList() {
        WaterQualityAlertDashboard result = new WaterQualityAlertDashboard();
        QueryWrapper<WaterQualityAlertCountDO> queryWrapper = new QueryWrapper<>();
        QueryWrapper<WaterQualityAlertCountDO> queryWrapper1 = new QueryWrapper<>();
        String year = String.valueOf(DateUtil.thisYear());
        String month = String.valueOf(DateUtil.thisMonth());
        LocalDate nowDay = LocalDate.now();
        LocalDate twoWeeksBefore = nowDay.plusDays(-14);
        int day = DateUtil.thisDayOfMonth();
        ;

        queryWrapper1.eq("data_date", nowDay);
        queryWrapper.ge("data_date", twoWeeksBefore);
        List<WaterQualityAlertCountDO> waterQualityAlertCountNowdayDOS = waterQualityAlertCountMapper.selectList(queryWrapper1);
        List<WaterQualityAlertCountDO> waterQualityAlertCountDOS = waterQualityAlertCountMapper.selectList(queryWrapper);


//        List<WaterQualityAlertCountDO> dayDatas = waterQualityAlertCountDOS.stream()
//                .filter(data -> day == data.getDataDate().getDayOfMonth())
//                .collect(Collectors.toList());

        /*------出厂水-----*/
        Map<Integer, Optional<Integer>> dayProducedWaterQualityMap = waterQualityAlertCountNowdayDOS.stream()
                .filter(data -> data.getWaterType() == 0)
                .collect(Collectors.groupingBy(WaterQualityAlertCountDO::getAlertType,
                        Collectors.mapping(WaterQualityAlertCountDO::getAlertCount,
                                Collectors.reducing(Integer::sum))));

        HashMap<Integer, Integer> dayProducedWaterQuality = MapUtil.newHashMap();
        for (Integer dataCount : dayProducedWaterQualityMap.keySet()) {
            dayProducedWaterQuality.put(dataCount, dayProducedWaterQualityMap.get(dataCount).isPresent() ?
                    dayProducedWaterQualityMap.get(dataCount).get() : 0);
        }
//        HashMap<Integer, Integer> dayProducedWaterQuality = MapUtil.newHashMap();
//        dayProducedWaterQuality.put(0, 5);
//        dayProducedWaterQuality.put(1, 2);
//        dayProducedWaterQuality.put(2, 8);
//        dayProducedWaterQuality.put(3, 7);
        // 若某个类型没有告警则设为0
        Integer numProduced0 = dayProducedWaterQuality.get(0);
        Integer numProduced1 = dayProducedWaterQuality.get(1);
        Integer numProduced2 = dayProducedWaterQuality.get(2);
        Integer numProduced3 = dayProducedWaterQuality.get(3);

        if (numProduced0==null){
            dayProducedWaterQuality.put(0,0);
        }
        if (numProduced1==null){
            dayProducedWaterQuality.put(1,0);
        }
        if (numProduced2==null){
            dayProducedWaterQuality.put(2,0);
        }
        if (numProduced3==null){
            dayProducedWaterQuality.put(3,0);
        }

        result.setDayProducedWaterQuality(dayProducedWaterQuality);

        /*------末梢水-----*/
        Map<Integer, Optional<Integer>> dayTabWaterQualityMap = waterQualityAlertCountNowdayDOS.stream()
                .filter(data -> data.getWaterType() == 1)
                .collect(Collectors.groupingBy(WaterQualityAlertCountDO::getAlertType,
                        Collectors.mapping(WaterQualityAlertCountDO::getAlertCount,
                                Collectors.reducing(Integer::sum))));

        HashMap<Integer, Integer> dayTabWaterQuality = MapUtil.newHashMap();
        for (Integer dataCount : dayTabWaterQualityMap.keySet()) {
            dayTabWaterQuality.put(dataCount, dayTabWaterQualityMap.get(dataCount).isPresent() ?
                    dayTabWaterQualityMap.get(dataCount).get() : 0);
        }
//        HashMap<Integer, Integer> dayTabWaterQuality = MapUtil.newHashMap();
//        dayTabWaterQuality.put(0, 4);
//        dayTabWaterQuality.put(1, 1);
//        dayTabWaterQuality.put(2, 2);
//        dayTabWaterQuality.put(3, 7);
        // 若某个类型没有告警则设为0
        Integer numTabWater0 = dayTabWaterQuality.get(0);
        Integer numTabWater1 = dayTabWaterQuality.get(1);
        Integer numTabWater2 = dayTabWaterQuality.get(2);
        Integer numTabWater3 = dayTabWaterQuality.get(3);

        if (numTabWater0==null){
            dayTabWaterQuality.put(0,0);
        }
        if (numTabWater1==null){
            dayTabWaterQuality.put(1,0);
        }
        if (numTabWater2==null){
            dayTabWaterQuality.put(2,0);
        }
        if (numTabWater3==null){
            dayTabWaterQuality.put(3,0);
        }
        result.setDayTabWaterQuality(dayTabWaterQuality);

        /*------月出厂水列表-----*/
//        Map<String, Optional<Integer>> dayProducedWaterQualityMonthMap = waterQualityAlertCountDOS.stream()
//                .filter(data -> data.getWaterType() == 0)
//                .collect(Collectors.groupingBy(WaterQualityAlertCountDO::getMonthValue,
//                        Collectors.mapping(WaterQualityAlertCountDO::getAlertCount,
//                                Collectors.reducing(Integer::sum))));

        //按照类型、月份分类求和
        Map<Integer, Map<LocalDate, Optional<Integer>>> dayProducedWaterQualityMonthMap = waterQualityAlertCountDOS.stream()
                .filter(data -> data.getWaterType() == 0)
                .collect(Collectors.groupingBy(WaterQualityAlertCountDO::getAlertType,
                        Collectors.groupingBy(WaterQualityAlertCountDO::getDataDate,
                                Collectors.mapping(WaterQualityAlertCountDO::getAlertCount,
                                        Collectors.reducing(Integer::sum)))));


        Map<Integer, TreeMap<String, Integer>>  dayProducedWaterQualityMonth = MapUtil.newHashMap();
        for (Integer alertType : dayProducedWaterQualityMonthMap.keySet()) {
            Map<LocalDate, Optional<Integer>> stringOptionalMap = dayProducedWaterQualityMonthMap.get(alertType);
            Map<String, Integer> alertTypeMonthMap = MapUtil.newHashMap();
            for (LocalDate s : stringOptionalMap.keySet()) {
                if (stringOptionalMap.get(s).isPresent())
                    alertTypeMonthMap.put(String.valueOf(s), stringOptionalMap.get(s).get());
            }
            dayProducedWaterQualityMonth.put(alertType, new TreeMap<>(alertTypeMonthMap));
        }

        result.setDayProducedWaterQualityMonth(new TreeMap<>(dayProducedWaterQualityMonth));

        /*-----月末梢水列表------*/

        //按照类型、月份分类求和
        Map<Integer, Map<LocalDate, Optional<Integer>>> dayTabWaterQualityMonthMap = waterQualityAlertCountDOS.stream()
                .filter(data -> data.getWaterType() == 1)
                .collect(Collectors.groupingBy(WaterQualityAlertCountDO::getAlertType,
                        Collectors.groupingBy(WaterQualityAlertCountDO::getDataDate,
                                Collectors.mapping(WaterQualityAlertCountDO::getAlertCount,
                                        Collectors.reducing(Integer::sum)))));


        Map<Integer, TreeMap<String, Integer>>  dayTabWaterQualityMonth = MapUtil.newHashMap();
        for (Integer alertType : dayTabWaterQualityMonthMap.keySet()) {
            Map<LocalDate, Optional<Integer>> stringOptionalMap = dayTabWaterQualityMonthMap.get(alertType);
            Map<String, Integer> alertTypeMonthMap = MapUtil.newHashMap();
            for (LocalDate s : stringOptionalMap.keySet()) {
                if (stringOptionalMap.get(s).isPresent())
                    alertTypeMonthMap.put(String.valueOf(s), stringOptionalMap.get(s).get());
            }
            dayTabWaterQualityMonth.put(alertType, new TreeMap<>(alertTypeMonthMap));
        }

        result.setDayTabWaterQualityMonth(new TreeMap<>(dayTabWaterQualityMonth));

        return CommonResult.success(result);
    }

    @GetMapping("/water-quality-alert-list1")
    @Operation(summary = "获得水质统计列表")
    public CommonResult<WaterQualityAlertDashboard> getWaterQualityAlertCountList1() {
        WaterQualityAlertDashboard result = new WaterQualityAlertDashboard();
        QueryWrapper<WaterQualityAlertCountDO> queryWrapper = new QueryWrapper<>();
        String year = String.valueOf(DateUtil.thisYear());
        String month = String.valueOf(DateUtil.thisMonth());
        int day = DateUtil.thisDayOfMonth();
        ;

        queryWrapper.eq("year_value", year);
        List<WaterQualityAlertCountDO> waterQualityAlertCountDOS = waterQualityAlertCountMapper.selectList(queryWrapper);

//        List<WaterQualityAlertCountDO> dayDatas = waterQualityAlertCountDOS.stream()
//                .filter(data -> day == data.getDataDate().getDayOfMonth())
//                .collect(Collectors.toList());

        /*------出厂水-----*/
//        Map<Integer, Optional<Integer>> dayProducedWaterQualityMap = dayDatas.stream()
//                .filter(data -> data.getWaterType() == 0)
//                .collect(Collectors.groupingBy(WaterQualityAlertCountDO::getAlertType,
//                        Collectors.mapping(WaterQualityAlertCountDO::getAlertCount,
//                                Collectors.reducing(Integer::sum))));
//
//        HashMap<Integer, Integer> dayProducedWaterQuality = MapUtil.newHashMap();
//        for (Integer dataCount : dayProducedWaterQualityMap.keySet()) {
//            dayProducedWaterQuality.put(dataCount, dayProducedWaterQualityMap.get(dataCount).isPresent() ?
//                    dayProducedWaterQualityMap.get(dataCount).get() : 0);
//        }
        HashMap<Integer, Integer> dayProducedWaterQuality = MapUtil.newHashMap();
        dayProducedWaterQuality.put(0, 5);
        dayProducedWaterQuality.put(1, 2);
        dayProducedWaterQuality.put(2, 8);
        dayProducedWaterQuality.put(3, 7);
        result.setDayProducedWaterQuality(dayProducedWaterQuality);

        /*------末梢水-----*/
//        Map<Integer, Optional<Integer>> dayTabWaterQualityMap = dayDatas.stream()
//                .filter(data -> data.getWaterType() == 1)
//                .collect(Collectors.groupingBy(WaterQualityAlertCountDO::getAlertType,
//                        Collectors.mapping(WaterQualityAlertCountDO::getAlertCount,
//                                Collectors.reducing(Integer::sum))));
//
//        HashMap<Integer, Integer> dayTabWaterQuality = MapUtil.newHashMap();
//        for (Integer dataCount : dayTabWaterQualityMap.keySet()) {
//            dayTabWaterQuality.put(dataCount, dayTabWaterQualityMap.get(dataCount).isPresent() ?
//                    dayTabWaterQualityMap.get(dataCount).get() : 0);
//        }
        HashMap<Integer, Integer> dayTabWaterQuality = MapUtil.newHashMap();
        dayTabWaterQuality.put(0, 4);
        dayTabWaterQuality.put(1, 1);
        dayTabWaterQuality.put(2, 2);
        dayTabWaterQuality.put(3, 7);
        result.setDayTabWaterQuality(dayTabWaterQuality);

        /*------月出厂水列表-----*/
//        Map<String, Optional<Integer>> dayProducedWaterQualityMonthMap = waterQualityAlertCountDOS.stream()
//                .filter(data -> data.getWaterType() == 0)
//                .collect(Collectors.groupingBy(WaterQualityAlertCountDO::getMonthValue,
//                        Collectors.mapping(WaterQualityAlertCountDO::getAlertCount,
//                                Collectors.reducing(Integer::sum))));

        //按照类型、月份分类求和
        Map<Integer, Map<String, Optional<Integer>>> dayProducedWaterQualityMonthMap = waterQualityAlertCountDOS.stream()
                .filter(data -> data.getWaterType() == 0)
                .collect(Collectors.groupingBy(WaterQualityAlertCountDO::getAlertType,
                        Collectors.groupingBy(WaterQualityAlertCountDO::getMonthValue,
                                Collectors.mapping(WaterQualityAlertCountDO::getAlertCount,
                                        Collectors.reducing(Integer::sum)))));


        Map<Integer, TreeMap<String, Integer>>  dayProducedWaterQualityMonth = MapUtil.newHashMap();
        for (Integer alertType : dayProducedWaterQualityMonthMap.keySet()) {
            Map<String, Optional<Integer>> stringOptionalMap = dayProducedWaterQualityMonthMap.get(alertType);
            Map<String, Integer> alertTypeMonthMap = MapUtil.newHashMap();
            for (String s : stringOptionalMap.keySet()) {
                if (stringOptionalMap.get(s).isPresent())
                    alertTypeMonthMap.put(s, stringOptionalMap.get(s).get());
            }
            dayProducedWaterQualityMonth.put(alertType, new TreeMap<>(alertTypeMonthMap));
        }

        result.setDayProducedWaterQualityMonth(new TreeMap<>(dayProducedWaterQualityMonth));

        /*-----月末梢水列表------*/

        //按照类型、月份分类求和
        Map<Integer, Map<String, Optional<Integer>>> dayTabWaterQualityMonthMap = waterQualityAlertCountDOS.stream()
                .filter(data -> data.getWaterType() == 1)
                .collect(Collectors.groupingBy(WaterQualityAlertCountDO::getAlertType,
                        Collectors.groupingBy(WaterQualityAlertCountDO::getMonthValue,
                                Collectors.mapping(WaterQualityAlertCountDO::getAlertCount,
                                        Collectors.reducing(Integer::sum)))));


        Map<Integer, TreeMap<String, Integer>>  dayTabWaterQualityMonth = MapUtil.newHashMap();
        for (Integer alertType : dayTabWaterQualityMonthMap.keySet()) {
            Map<String, Optional<Integer>> stringOptionalMap = dayTabWaterQualityMonthMap.get(alertType);
            Map<String, Integer> alertTypeMonthMap = MapUtil.newHashMap();
            for (String s : stringOptionalMap.keySet()) {
                if (stringOptionalMap.get(s).isPresent())
                    alertTypeMonthMap.put(s, stringOptionalMap.get(s).get());
            }
            dayTabWaterQualityMonth.put(alertType, new TreeMap<>(alertTypeMonthMap));
        }

        result.setDayTabWaterQualityMonth(new TreeMap<>(dayTabWaterQualityMonth));

        return CommonResult.success(result);
    }


    @GetMapping("/water-use-statics-list1")
    @Operation(summary = "获得水量统计列表")
    public CommonResult<WaterUseStaticsDashboard> getWaterUseStaticsDashboard() {
        WaterUseStaticsDashboard result = new WaterUseStaticsDashboard();

        QueryWrapper<WaterCountDO> queryWrapper = new QueryWrapper<>();
        String year = String.valueOf(DateUtil.thisYear());
        queryWrapper.eq("year_value", year);
        List<WaterCountDO> thisYearData = waterCountMapper.selectList(queryWrapper);

        //月供水
        Map<String, Long> waterSupplyMonth = thisYearData.stream().filter(data -> data.getWaterType() == 0)
                .collect(Collectors.groupingBy(WaterCountDO::getMonthValue,
                        Collectors.summingLong(WaterCountDO::getWaterCount)));

        Map<String, Double> waterSupplyMonthDouble = MapUtil.newHashMap();
        for (String s : waterSupplyMonth.keySet()) {
            waterSupplyMonthDouble.put(s, NumberUtil.div(waterSupplyMonth.get(s).doubleValue(),1000d));
        }

        result.setWaterSupplyMonth(new TreeMap<>(waterSupplyMonthDouble));

        //月售水
        Map<String, Long> waterSoledMonth = thisYearData.stream().filter(data -> data.getWaterType() == 1)
                .collect(Collectors.groupingBy(WaterCountDO::getMonthValue,
                        Collectors.summingLong(WaterCountDO::getWaterCount)));
        Map<String, Double> waterSoledMonthDouble = MapUtil.newHashMap();
        for (String s : waterSoledMonth.keySet()) {
            waterSoledMonthDouble.put(s, NumberUtil.div(waterSoledMonth.get(s).doubleValue(),1000d));
        }
        result.setWaterSoledMonth(new TreeMap<>(waterSoledMonthDouble));

        //todo 9月（前一月）总供水量比例， 同比（今年9月与上年9月对比），环比（9月和8月比较）
        WaterUseRatio waterSupplyRatio = new WaterUseRatio();
        waterSupplyRatio.setWaterRatio(59);
        waterSupplyRatio.setMomWaterRatio(1.8f);
        waterSupplyRatio.setQoqWaterRatio(2.2f);

        result.setWaterSupplyRatio(waterSupplyRatio);
        WaterUseRatio waterSoledRatio = new WaterUseRatio();
        waterSoledRatio.setWaterRatio(47);
        waterSoledRatio.setMomWaterRatio(1.3f);
        waterSoledRatio.setQoqWaterRatio(2.8f);
        result.setWaterSoledRatio(waterSoledRatio);


        return CommonResult.success(result);

    }

    @GetMapping("/water-use-statics-list")
    @Operation(summary = "获得水量产销差统计列表")
    public CommonResult<WaterUseStaticsDashboard> getWaterUseStaticsDValueDashboard() {
        WaterUseStaticsDashboard result = new WaterUseStaticsDashboard();

        QueryWrapper<WaterCountDO> queryWrapper = new QueryWrapper<>();
        String year = String.valueOf(DateUtil.thisYear());
        queryWrapper.eq("year_value", year);
        List<WaterCountDO> thisYearData = waterCountMapper.selectList(queryWrapper);

        //月供水
        Map<String, Long> waterSupplyMonth = thisYearData.stream().filter(data -> data.getWaterType() == 0)
                .collect(Collectors.groupingBy(WaterCountDO::getMonthValue,
                        Collectors.summingLong(WaterCountDO::getWaterCount)));

        Map<String, Double> waterSupplyMonthDouble = MapUtil.newHashMap();
        for (String s : waterSupplyMonth.keySet()) {
            waterSupplyMonthDouble.put(s, NumberUtil.div(waterSupplyMonth.get(s).doubleValue(),10000d));
        }

        result.setWaterSupplyMonth(new TreeMap<>(waterSupplyMonthDouble));

        //月售水
        Map<String, Long> waterSoledMonth = thisYearData.stream().filter(data -> data.getWaterType() == 1)
                .collect(Collectors.groupingBy(WaterCountDO::getMonthValue,
                        Collectors.summingLong(WaterCountDO::getWaterCount)));
        Map<String, Double> waterSoledMonthDouble = MapUtil.newHashMap();
        for (String s : waterSoledMonth.keySet()) {
            waterSoledMonthDouble.put(s, NumberUtil.div(waterSoledMonth.get(s).doubleValue(),10000d));
        }
        result.setWaterSoledMonth(new TreeMap<>(waterSoledMonthDouble));

        // 计算产销差
        Map<String, Double> waterSupplySoledDValueMonth = MapUtil.newHashMap();
        Map<String, Double> waterSupplySoledDValueRateMonth = MapUtil.newHashMap();
        for (String s : waterSupplyMonth.keySet()){
            if (waterSoledMonth.containsKey(s)){
                waterSupplySoledDValueMonth.put(s, NumberUtil.div(waterSupplyMonth.get(s)-waterSoledMonth.get(s),10000d));
                waterSupplySoledDValueRateMonth.put(s, NumberUtil.div((waterSupplyMonth.get(s).doubleValue()-waterSoledMonth.get(s).doubleValue())/waterSupplyMonth.get(s).doubleValue(),100d));
            }
        }
        result.setWaterSupplySoledDValueMonth(new TreeMap<>(waterSupplySoledDValueMonth));
        result.setWaterSupplySoledDValueRateMonth(new TreeMap<>(waterSupplySoledDValueRateMonth));

        //todo 9月（前一月）总供水量比例， 同比（今年9月与上年9月对比），环比（9月和8月比较）
        WaterUseRatio waterSupplyRatio = new WaterUseRatio();
        waterSupplyRatio.setWaterRatio(59);
        waterSupplyRatio.setMomWaterRatio(1.8f);
        waterSupplyRatio.setQoqWaterRatio(2.2f);

        result.setWaterSupplyRatio(waterSupplyRatio);
        WaterUseRatio waterSoledRatio = new WaterUseRatio();
        waterSoledRatio.setWaterRatio(47);
        waterSoledRatio.setMomWaterRatio(1.3f);
        waterSoledRatio.setQoqWaterRatio(2.8f);
        result.setWaterSoledRatio(waterSoledRatio);


        return CommonResult.success(result);

    }

}
